package com.sky.utils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

import org.springframework.stereotype.Service;

import java.security.*;
import java.util.Base64;

/**
 * 数据加解密工具
 *
 * @author majun
 * @package com.sky.utils
 * @date 2024/11/20 12:38
 */

@Service
public class HybridEncryptionUtil {

    // 加密方法
    public String[] encryptData(String data, PublicKey rsaPublicKey) throws Exception {
        // 生成AES密钥
        KeyGenerator aesKeyGenerator = KeyGenerator.getInstance("AES");
        aesKeyGenerator.init(256);
        SecretKey aesKey = aesKeyGenerator.generateKey();

        // 生成IV
        byte[] ivBytes = new byte[16];
        new SecureRandom().nextBytes(ivBytes);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);

        // 使用AES加密数据
        Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        aesCipher.init(Cipher.ENCRYPT_MODE, aesKey, ivParameterSpec);
        byte[] encryptedData = aesCipher.doFinal(data.getBytes());

        // 使用RSA加密AES密钥
        Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        rsaCipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey);
        byte[] encryptedAesKey = rsaCipher.doFinal(aesKey.getEncoded());

        // Base64编码加密后的数据、AES密钥和IV
        String base64EncryptedData = Base64.getEncoder().encodeToString(encryptedData);
        String base64EncryptedAesKey = Base64.getEncoder().encodeToString(encryptedAesKey);
        String base64Iv = Base64.getEncoder().encodeToString(ivBytes);

        return new String[]{base64EncryptedData, base64EncryptedAesKey, base64Iv};
    }

    // 解密方法
    public String decryptData(String encryptedDataBase64, String encryptedAesKeyBase64, String ivBase64, PrivateKey rsaPrivateKey) throws Exception {
        // 解密AES密钥
        Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        rsaCipher.init(Cipher.DECRYPT_MODE, rsaPrivateKey);
        byte[] encryptedAesKey = Base64.getDecoder().decode(encryptedAesKeyBase64);
        byte[] aesKeyBytes = rsaCipher.doFinal(encryptedAesKey);
        SecretKey aesKey = new javax.crypto.spec.SecretKeySpec(aesKeyBytes, "AES");

        // 解密数据
        byte[] ivBytes = Base64.getDecoder().decode(ivBase64);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);

        Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        aesCipher.init(Cipher.DECRYPT_MODE, aesKey, ivParameterSpec);
        byte[] encryptedData = Base64.getDecoder().decode(encryptedDataBase64);
        byte[] decryptedData = aesCipher.doFinal(encryptedData);

        return new String(decryptedData);
    }
}

